package com.yqb.study.config.mq;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 1.Queue(String name, boolean durable),durable为true是持久化队列(重启消息仍在),durable为false是非持久化队列(重启消息不在)
 * 2.Topic交换机,bindKey中符号“#”匹配一个或多个词,符号“*”匹配不多不少一个词。
 * 
 * 注意:1.路由规则是持续累加的,代码中修改前和修改后的路由规则在rabbit mq中都会生效,需要通过管理平台进行手工解绑,不然消息会错误发送;
 *     2.测试发现交换机后的队列,如果有多个消费者,只会有一个固定消费者获得消息,和work还不像;
 *     3.清除rabbit mq中现有的队列方法:
 *         查看所有队列信息rabbitmqctl list_queues,
 *         关闭应用（关闭当前启动的节点）rabbitmqctl stop_app,
 *         从管理数据库中移除所有数据，例如配置过的用户和虚拟宿主, 删除所有持久化的消息（这个命令要在rabbitmqctl stop_app之后使用,用户还要重新分配）rabbitmqctl reset,
 *         启动应用，和上述关闭命令配合使用，达到清空队列的目的rabbitmqctl start_app
 */
@Configuration
public class MqConfig {
	
	// fanout交换机接入两个queue
	// sender发送消息到exchage
	// 交换机忽略routeKey与bindKey,将受到的消息广播到所有queue中
	// 若干消费者选择合适的queue进行监听获取消息
	public static final String FANOUT_QUEUE1 = "fanout.queue1";
	public static final String FANOUT_QUEUE2 = "fanout.queue2";
	public static final String FANOUT_EXCHANGE = "fanoutExchage";	
	
	// direct交换机接入两个queue
	// sender发送消息到exchage
	// direct交换机根据routeKey与bindKey进行严格匹配生成路由表,转发消息到对应的queue中
	// 若干消费者选择合适的queue进行监听获取消息
	public static final String DIRECT_QUEUE1 = "direct.queue1";
	public static final String DIRECT_QUEUE1_BIND_KEY = "direct.queue1";
	public static final String DIRECT_QUEUE2 = "direct.queue2";
	public static final String DIRECT_QUEUE2_BIND_KEY = "direct.queue2";
	public static final String DIRECT_EXCHANGE = "directExchage";		

	// topic交换机接入两个queue
	// sender发送消息到exchage
	// topic交换机根据routeKey与bindKey进行模糊匹配生成路由表,转发消息到对应的queue中
	// 若干消费者选择合适的queue进行监听获取消息
	public static final String TOPIC_QUEUE1 = "topic.queue1";
	public static final String TOPIC_QUEUE1_ROUTE_KEY_PREFIX = "topic.queue1";
	public static final String TOPIC_QUEUE1_BIND_KEY = "topic.queue1.#";
	public static final String TOPIC_QUEUE2 = "topic.queue2";
	public static final String TOPIC_QUEUE2_ROUTE_KEY_PREFIX = "topic.queue2";
	public static final String TOPIC_QUEUE2_BIND_KEY = "topic.#";
	public static final String TOPIC_EXCHANGE = "topicExchage";


	/**
	 * fanout模式交换机Exchange
	 */
	@Bean
	public Queue fanoutQueue1() {
		return new Queue(FANOUT_QUEUE1, false);
	}

	@Bean
	public Queue fanoutQueue2() {
		return new Queue(FANOUT_QUEUE2, false);
	}	
	
	@Bean
	public FanoutExchange fanoutExchage() {
		return new FanoutExchange(FANOUT_EXCHANGE);
	}

	@Bean
	public Binding fanoutBinding1() {
		return BindingBuilder.bind(fanoutQueue1()).to(fanoutExchage());
	}

	@Bean
	public Binding fanoutBinding2() {
		return BindingBuilder.bind(fanoutQueue2()).to(fanoutExchage());
	}
	
	/**
	 * Topic模式 交换机Exchange
	 */
	@Bean
	public Queue directQueue1() {
		return new Queue(DIRECT_QUEUE1, false);
	}

	@Bean
	public Queue directQueue2() {
		return new Queue(DIRECT_QUEUE2, false);
	}

	@Bean
	public DirectExchange directExchage() {
		return new DirectExchange(DIRECT_EXCHANGE);
	}

	@Bean
	public Binding directBinding1() {
		// 将名为direct.queue1的队列绑定到交换机directExchage上,bindKey是direct.queue1
		return BindingBuilder.bind(directQueue1()).to(directExchage()).with(DIRECT_QUEUE1_BIND_KEY);
	}

	@Bean
	public Binding directBinding2() {
		// 将名为direct.queue2的队列绑定到交换机directExchage上,bindKey是direct.queue2
		return BindingBuilder.bind(directQueue2()).to(directExchage()).with(DIRECT_QUEUE2_BIND_KEY);
	}	

	/**
	 * Topic模式 交换机Exchange
	 */
	@Bean
	public Queue topicQueue1() {
		return new Queue(TOPIC_QUEUE1, false);
	}

	@Bean
	public Queue topicQueue2() {
		return new Queue(TOPIC_QUEUE2, false);
	}

	@Bean
	public TopicExchange topicExchage() {
		return new TopicExchange(TOPIC_EXCHANGE);
	}

	@Bean
	public Binding topicBinding1() {
		// 将名为topic.queue1的队列绑定到交换机topicExchage上,bindKey是topic.queue1.#
		return BindingBuilder.bind(topicQueue1()).to(topicExchage()).with(TOPIC_QUEUE1_BIND_KEY);
	}

	@Bean
	public Binding topicBinding2() {
		// 将名为topic.queue2的队列绑定到交换机topicExchage上,bindKey是topic.queue2.#
		return BindingBuilder.bind(topicQueue2()).to(topicExchage()).with(TOPIC_QUEUE2_BIND_KEY);
	}

//
//	/**
//	 * Header模式 交换机Exchange
//	 */
//	@Bean
//	public HeadersExchange headersExchage() {
//		return new HeadersExchange(HEADERS_EXCHANGE);
//	}
//
//	@Bean
//	public Queue headerQueue1() {
//		return new Queue(HEADER_QUEUE, true);
//	}
//
//	@Bean
//	public Binding headerBinding() {
//		Map<String, Object> map = new HashMap<String, Object>();
//		map.put("header1", "value1");
//		map.put("header2", "value2");
//		return BindingBuilder.bind(headerQueue1()).to(headersExchage()).whereAll(map).match();
//	}

}
